package com.eling.elcms.travel.service.impl;

import com.eling.elcms.basedoc.model.BusinessMessage;
import com.eling.elcms.basedoc.model.Room;
import com.eling.elcms.basedoc.model.Room.Status;
import com.eling.elcms.basedoc.model.TargetType;
import com.eling.elcms.basedoc.model.TaskType;
import com.eling.elcms.basedoc.service.IBusinessMessageManager;
import com.eling.elcms.basedoc.service.IRoomManager;
import com.eling.elcms.core.AppContext;
import com.eling.elcms.core.dao.hibernate.search.SearchCondition;
import com.eling.elcms.core.service.impl.GenericManagerImpl;
import com.eling.elcms.core.util.PropertyUtils;
import com.eling.elcms.ordermanager.service.IServicePointManager;
import com.eling.elcms.system.model.CommonUser;
import com.eling.elcms.travel.dao.ICheckInImplementDao;
import com.eling.elcms.travel.model.*;
import com.eling.elcms.travel.model.CheckIn.CheckOutStatus;
import com.eling.elcms.travel.model.CheckInImplement.CheckStatus;
import com.eling.elcms.travel.model.CheckInImplement.DataSource;
import com.eling.elcms.travel.model.CheckInImplement.PaymentMethod;
import com.eling.elcms.travel.model.CheckInImplement.StatementStatus;
import com.eling.elcms.travel.model.PlanItemGroup.CheckInStatus;
import com.eling.elcms.travel.model.RoomRegister.CheckInType;
import com.eling.elcms.travel.model.RoomRegister.RoomStatus;
import com.eling.elcms.travel.model.view.*;
import com.eling.elcms.travel.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CheckInImplementManagerImpl extends GenericManagerImpl<CheckInImplement, Long>
		implements ICheckInImplementManager {

	ICheckInImplementDao ciimplementDao;
	@Autowired
	private IRoomManager roomManager;
	@Autowired
	private IRoomRegisterManager roomRegisterM;
	@Autowired
	private IRoomPersonalInfoManager roomPersonM;
	@Autowired
	private IPlanItemGroupManager planItemGroupM;
	@Autowired
	private IGroupReserveManager groupReserveM;
	@Autowired
	private ICheckInManager checkInManager;
	@Autowired
	private IServicePointManager servicepointmanager;
	@Autowired
	private IAllianceSettlementManager allSetlManager;
	@Autowired
	private IAllianceSetlDetailManager allSetlDetManager;
	@Autowired
	private IRoomTypePriceManager roomTypePriceM;
	@Autowired
	private ISignUpRoomManager signUpRoomManager;
	@Autowired
	private IBusinessMessageManager businessMessageManager;
	
	@Autowired
	public void setDao(ICheckInImplementDao dao) {
		this.dao = dao;
		this.ciimplementDao = dao;
	}

	@Override
	public CheckInDetailView queryAll(CheckInImplement checkInImplement, Long pkRoom) {
		return ciimplementDao.queryAll(checkInImplement, pkRoom);
	}
	
	@Override
	public ImplementView saveAll(ImplementView checkInImplement) {
		List<RoomPersonalInfo> list = checkInImplement.getTemp();// 房间和人关系
		RoomRegister roomRegister = checkInImplement.getRoomRegister();// 房间登记
		RoomRegister roo = roomRegisterM.get(roomRegister.getPkRoomRegister());
		roo.setCheckInPrice(roomRegister.getCheckInPrice());
		roo.setCheckInPriceMark(roomRegister.getCheckInPriceMark());
		roo.setCheckInType(roomRegister.getCheckInType());
		roo.setWaterElectric(roomRegister.getWaterElectric());
		roo.setWaterMeter(roomRegister.getWaterMeter());
		roo.setElectricMeter(roomRegister.getElectricMeter());
		roo.setBreakfast(roomRegister.getBreakfast());
		roo.setPrice(roomRegister.getPrice());
		roo = roomRegisterM.save(roo);
		List<Long> pklist = new ArrayList<Long>();
		for (RoomPersonalInfo rpi : list) {
			pklist.add(rpi.getPkRoomPersonalInfo());
		}
		RoomPersonalInfo r = new RoomPersonalInfo();
		PropertyUtils.setProperty(r, "pkRoomPersonalInfoIn", pklist);
		List<RoomPersonalInfo> room = roomPersonM.query(r);
		for (RoomPersonalInfo pp : list) {
			for (RoomPersonalInfo p : room) {
				if (pp.getPkRoomPersonalInfo().equals(p.getPkRoomPersonalInfo())) {
					p.setCheckIn(pp.getCheckIn());
				}
			}
		}
		room = roomPersonM.save(room);
		ImplementView cv = new ImplementView();
		cv.setRoomRegister(roo);
		cv.setTemp(room);

		int j = 0;
		for (RoomPersonalInfo rps : room) {
			if (rps.getCheckIn()) {
				j++;
			}
		}

		// 至少有一个人登记才推送登记记录
		if (j > 0) {
			CheckIn ci = new CheckIn();
			ci.setRoomRegister(roo);
			// 根据房间去查询所有登记
			List<CheckIn> checkIn = checkInManager.query(ci);
			if (checkIn.isEmpty()) {
				// 推送入住登记
				ci.setRoomRegister(roo);
				ci.setCheckInImplement(room.get(0).getCheckInImplement());
				ci.setRegisterDate(new Date());
				CommonUser cu = (CommonUser) AppContext.curUser();
				ci.setOperator(cu);
				ci.setServicePoint(roo.getRoom().getOrgBuilding().getServicePoint());
				ci.setCheckInDate(room.get(0).getCheckInImplement().getGroupReserve().getCheckInDate());
				ci.setCheckOutDate(room.get(0).getCheckInImplement().getGroupReserve().getCheckOutDate());
				ci.setCheckOutStatus(CheckIn.CheckOutStatus.NoCheckOut);
				// ci.setStatementStatus(CheckIn.StatementStatus.NoStatement);
				// 该房间所有人都登记了
				if (j == room.size()) {
					ci.setStatus(CheckIn.Status.CheckIn);
				} else {
					ci.setStatus(CheckIn.Status.NoCheckIn);
				}
				ci.setVersion(0);
				// 保存新建的记录
				checkInManager.save(ci);
			} else {
				ci = checkIn.get(0);
				if (j == room.size()) {
					ci.setStatus(CheckIn.Status.CheckIn);
				} else {
					ci.setStatus(CheckIn.Status.NoCheckIn);
				}
				checkInManager.save(ci);
			}

			Room rm = roomManager.get(roo.getRoom().getPkRoom());
			rm.setStatus(Status.CheckIn);
			roomManager.save(rm);
		}
		return cv;
	}

	@Override
	public CheckInImplement save(CheckInImplement checkInImplement, List<RoomPersonalInfo> roomPersons, List<CheckInMeeting> checkInMeetings, List<SignUpRoom> signUpRooms, List<Dinner> dinners,List<CheckInCar> checkIncars) {

		CheckInDinner checkInDinner = checkInImplement.getCheckInDinner();
		checkInImplement = query(checkInImplement).get(0);
		if(checkInDinner == null){
			checkInDinner = new CheckInDinner();
			checkInDinner.setOperateDate(new Date());
			checkInDinner.setOperator((CommonUser)AppContext.curUser());
			checkInDinner.setStatus(CheckStatus.NoRequiement);
			checkInDinner.setVersion(0);
			checkInImplement.setCheckInDinner(checkInDinner);
		}
		// 初始状态的准备落实单保存后状态切换为已设置
		if (checkInImplement.getStatus() == CheckStatus.Initial) {
			checkInImplement.setStatus(CheckStatus.Edited);
		}
		
		// 入住准备落实单进入准备中状态时，房间整体进入待落实状态
		if (checkInImplement.getStatus() == CheckStatus.Doing) {
			checkInImplement.setRoomStatus(CheckStatus.Pending);
		}
		checkInImplement.setStatementStatus(CheckInImplement.StatementStatus.NoStatement);
		
		checkInImplement =save(checkInImplement);
				
		//保存车辆准备
		if(checkIncars!=null && !checkIncars.isEmpty()){
//			for (CheckInCar checkcar : checkIncars) {
//				//checkcar.setCheckInImplement(checkInImplement);
//				checkcar.setVersion(0);
//			}
			checkInImplement.setCheckInCar(new HashSet<>(checkIncars));
			checkInImplement = save(checkInImplement);
		}
		
		//checkinmeeting会议
		if(checkInMeetings!=null && !checkInMeetings.isEmpty()){
			for (CheckInMeeting checkMeeting : checkInMeetings) {
				checkMeeting.setHaveMeeting(true);
				checkMeeting.setCheckInImplement(checkInImplement);
			}
			checkInImplement.setCheckInMeetings(new HashSet<>(checkInMeetings));
			checkInImplement = save(checkInImplement);
		}
		
		// 保存房间和人设置信息
		if (checkInImplement.getDataSource()!=null&&checkInImplement.getDataSource().equals(DataSource.GroupReserve)) { // 老人团直接保存房间和人的信息
			if (roomPersons != null && roomPersons.size() > 0) {
				for (RoomPersonalInfo person : roomPersons) {
					person.getRoomRegister().setStatus(CheckStatus.Pending);
				}
				Set<RoomPersonalInfo> rpSet = checkInImplement.getRoomPersonalInfos();
				rpSet.clear();
				roomPersons = roomPersonM.save(roomPersons);
				rpSet.addAll(roomPersons);
				checkInImplement.setRoomPersonalInfos(rpSet);
				checkInImplement.setRoomStatus(CheckStatus.Pending);
			} else {
				checkInImplement.setRoomStatus(CheckStatus.NoRequiement);
			}
		} else {
			if(!signUpRooms.isEmpty()){
				signUpRoomManager.save(signUpRooms);
			}
			//如果是体验的 帮助生成roompersonsal
			if(checkInImplement.getNonMemGroupReserve().getNonMemberGroup().getSignUpType() == NonMemberGroup.SignUpType.Experience){
				Set<NonMemberRegister> nonMemberRegisters = checkInImplement.getNonMemGroupReserve().getNonMemberGroup().getSignUps();
				List<RoomPersonalInfo> roomPersonalInfos = new ArrayList<>();
				for (NonMemberRegister nonMemberRegister : nonMemberRegisters) {
					RoomPersonalInfo tmp = new  RoomPersonalInfo();
					tmp.setCheckInImplement(checkInImplement);
					tmp.setNonMemberRegister(nonMemberRegister);
					RoomRegister roomRegister = new  RoomRegister();
					roomRegister.setCheckInType(RoomRegister.CheckInType.NonMember);
					roomRegister.setStatus(CheckInImplement.CheckStatus.Pending);
					tmp.setRoomRegister(roomRegisterM.save(roomRegister));
					tmp.setCheckIn(false);
					roomPersonalInfos.add(tmp);
				}
				roomPersonalInfos = roomPersonM.save(roomPersonalInfos);
				Set<RoomPersonalInfo> rpSet = checkInImplement.getRoomPersonalInfos();
				rpSet.clear();
				rpSet.addAll(roomPersonalInfos);
				checkInImplement.setRoomPersonalInfos(rpSet);
			}
		}
	

		return save(checkInImplement);
	}

	@Override
	public List<RoomPersonalInfo> queryRoomPersonal(CheckInImplement checkInImplement) {
		checkInImplement = get(checkInImplement.getPkCIImplement());
		List<RoomPersonalInfo> result = new ArrayList<RoomPersonalInfo>();

		if (checkInImplement.getRoomPersonalInfos() != null && !checkInImplement.getRoomPersonalInfos().isEmpty()) {
			for (RoomPersonalInfo rpInfo : checkInImplement.getRoomPersonalInfos()) {
				if (rpInfo.getSignUpRegister() != null && (rpInfo.getSignUpRegister().getExitGroup() == null
						|| !rpInfo.getSignUpRegister().getExitGroup())) { // 老人团
					result.add(rpInfo);
				} else if (rpInfo.getNonMemberRegister().getSignUpRegister().getExitGroup() == null
						|| !rpInfo.getNonMemberRegister().getSignUpRegister().getExitGroup()) { // 散客团
					result.add(rpInfo);
				}
			}
		} else{
			for (SignUpRegister signUp : checkInImplement.getGroupReserve().getPlanItemGroup().getSignUps()) {
				if (signUp.getExitGroup() == null || !signUp.getExitGroup()) {
					RoomPersonalInfo person = new RoomPersonalInfo();
					person.setSignUpRegister(signUp);
					result.add(person);
				}
			}
		}

		return result;
	}

	@Override
	public CheckInImplement setCiiCheckStatusConfirm(CheckInImplement checkInImplement) {
		checkInImplement = get(checkInImplement.getPkCIImplement());
		if ( checkInImplement.getCheckInDinner() != null
				&& checkInImplement.getCheckInDinner().getStatus() != null
				&& (checkInImplement.getCheckInDinner().getStatus() == CheckStatus.Pended
						|| checkInImplement.getCheckInDinner().getStatus() == CheckStatus.NoRequiement)
				&& checkInImplement.getRoomStatus() != null && checkInImplement.getRoomStatus() == CheckStatus.Pended) {
			
			Boolean flag = true;
			Set<CheckInCar> checkIncar = checkInImplement.getCheckInCar();
			Set<CheckInMeeting> checkInMeetings = checkInImplement.getCheckInMeetings();
			if( checkIncar != null && !checkIncar.isEmpty()){
				for (CheckInCar car : checkIncar) {
					if(!(car.getStatus() !=null && (car.getStatus() == CheckStatus.Pended || car.getStatus() == CheckStatus.NoRequiement))){
						flag = false;
						break;
					}
				}
			}
			
			if(checkInMeetings != null && !checkInMeetings.isEmpty()){
				for (CheckInMeeting c : checkInImplement.getCheckInMeetings()) {
					if(!(c.getStatus() != null && (c.getStatus() == CheckStatus.Pended) || c.getStatus() == CheckStatus.NoRequiement)){
						flag = false;
						break;
					}
				}
			}
			if(flag){
				checkInImplement.setStatus(CheckStatus.Confirmed);
				checkInImplement = super.save(checkInImplement);
				businessMessageManager.saveBusinessMessage(new BusinessMessage(TargetType.Role,TaskType.WaterElectricCheckIn,checkInImplement.getPkCIImplement()));
			}
			
		}

		return checkInImplement;
	}

	@Override
	public List<CheckInImplement> queryAllCheckInOrder(CheckInImplement cii, Long pkServicePoint, Date startDate,
			Date endDate) {
		List<CheckInImplement> returnList = new ArrayList<>();

		// 查询机构、联盟团的入住准备落实单
		PropertyUtils.setProperty(cii, "dataSource", DataSource.GroupReserve);
		PropertyUtils.setProperty(cii, "servicePoint.pkServicePoint", pkServicePoint);
		PropertyUtils.setProperty(cii, "groupReserve.orderString", "checkInDate:desc");
		PropertyUtils.setProperty(cii, "groupReserve.checkInDate", startDate);
		PropertyUtils.setProperty(cii, "groupReserve.checkInDateEnd", endDate);
		PropertyUtils.setProperty(cii, "orderString", "groupReserve.checkInDate");
		List<CheckInImplement> ciiOneList = ciimplementDao.query(cii);
		if (!ciiOneList.isEmpty()) {
			for (CheckInImplement ciiOne : ciiOneList) {
				if (ciiOne.getGroupReserve().getPlanItemGroup().getIsAbolished() == null
						|| !ciiOne.getGroupReserve().getPlanItemGroup().getIsAbolished()) {
					returnList.add(ciiOne);
				}
			}
		}

		// 查询散客团的入住准备落实单
		PropertyUtils.setProperty(cii, "dataSource", DataSource.NonMember);
		PropertyUtils.setProperty(cii, "groupReserve", null);
		PropertyUtils.setProperty(cii, "nonMemGroupReserve.nonMemberGroup.checkInDate", startDate);
		PropertyUtils.setProperty(cii, "nonMemGroupReserve.nonMemberGroup.checkInDateEnd", endDate);
		PropertyUtils.setProperty(cii, "orderString", "nonMemGroupReserve.nonMemberGroup.checkInDate");
		List<CheckInImplement> ciiTwoList = ciimplementDao.query(cii);
		if (!ciiTwoList.isEmpty()) {
			for (CheckInImplement ciiTwo : ciiTwoList) {
				if (ciiTwo.getNonMemGroupReserve().getNonMemberGroup().getIsAbolished() == null
						|| !ciiTwo.getNonMemGroupReserve().getNonMemberGroup().getIsAbolished()) {
					returnList.add(ciiTwo);
				}
			}
		}

		Collections.sort(returnList, new Comparator<CheckInImplement>() {
			public int compare(CheckInImplement o1, CheckInImplement o2) {
				Date date1 = null;
				Date date2 = null;
				// 老人团
				if (o1.getDataSource().name().equals(DataSource.GroupReserve.name())) {
					date1 = o1.getGroupReserve().getCheckInDate();
				} else {// 散客
					date1 = o1.getNonMemGroupReserve().getNonMemberGroup().getCheckInDate();
				}
				// 老人团
				if (o2.getDataSource().name().equals(DataSource.GroupReserve.name())) {
					date2 = o2.getGroupReserve().getCheckInDate();
				} else {// 散客
					date2 = o2.getNonMemGroupReserve().getNonMemberGroup().getCheckInDate();
				}
				return date1.compareTo(date2);
			};
		});

		return returnList;
	}

	@Override
	public List<SettlementView> querySettlement(Long pkServicePoint, String status, Date checkOutDate,
			Date checkOutDateEnd,String paymentMethod) {

		List<SettlementView> returnlist = new ArrayList<SettlementView>();

		// 根据从条件获得所有满足条件的结算单(入住直属)
		CheckInImplement cii = new CheckInImplement();
		cii.setServicePoint(servicepointmanager.get(pkServicePoint));
		;
		if (status.equals(CheckInImplement.ConfirmStatus.NoConfirm.name())) {
			cii.setConfirmStatus(CheckInImplement.ConfirmStatus.NoConfirm);
		} else {
			cii.setConfirmStatus(CheckInImplement.ConfirmStatus.Confirm);
		}
		PropertyUtils.setProperty(cii, "groupReserve.checkOutDate", checkOutDate);
		PropertyUtils.setProperty(cii, "groupReserve.checkOutDateEnd", checkOutDateEnd);
		PropertyUtils.setProperty(cii, "groupReserve.planItemGroup.checkInStatus", PlanItemGroup.CheckInStatus.Finish);
		cii.setStatementStatus(CheckInImplement.StatementStatus.Statement);
		List<CheckInImplement> list = ciimplementDao.query(cii);

		// 筛选入住直属的结算单
		for (CheckInImplement checkIn : list) {
			SettlementView view = new SettlementView();
			view.setPk(checkIn.getPkCIImplement());
			view.setVersion(checkIn.getVersion());
			// 联盟入住直属
			if (checkIn.getGroupReserve().getPlanItemGroup().getAlliance()) {
				view.setPlanItem(checkIn.getGroupReserve().getPlanItemGroup().getAllianceOrg().getName());
				view.setType("联盟入住直属");
			}
			// 直属入住直属
			else {
				view.setType("直属入住直属");
				view.setPlanItem(checkIn.getGroupReserve().getPlanItemGroup().getServicePoint().getName());
			}
			view.setIsSales(checkIn.getIsSales());
			view.setCheckInDate(checkIn.getGroupReserve().getCheckInDate());
			view.setCheckOutDate(checkIn.getGroupReserve().getCheckOutDate());
			view.setName(checkIn.getGroupReserve().getPlanItemGroup().getPlanItem().getDestination().getName());
			view.setBalance(checkIn.getBalance());
			view.setConfirmStatus(checkIn.getConfirmStatus().name());
			view.setConfirmDate(checkIn.getConfirmDate());
			view.setPaymentMethods(new ArrayList<>(checkIn.getPaymentMethods()));
			
			
			if("all".equals(paymentMethod)){
				returnlist.add(view);
			}else{
				for(PaymentMethod p: checkIn.getPaymentMethods()){
					if(paymentMethod.equals(p.toString())){
						returnlist.add(view);
						break;
					}
				}
			}
			
			//returnlist.add(view);
		}

		// 根据从条件获得所有满足条件的结算单(入住联盟)
		GroupReserve reserve = new GroupReserve();
		PropertyUtils.setProperty(reserve, "checkOutDate", checkOutDate);
		PropertyUtils.setProperty(reserve, "checkOutDateEnd", checkOutDateEnd);
		PropertyUtils.setProperty(reserve, "planItemGroup.servicePoint.pkServicePoint", pkServicePoint);
		PropertyUtils.setProperty(reserve, "planItemGroup.alliance", false);
		PropertyUtils.setProperty(reserve, "planItemGroup.checkInStatus", PlanItemGroup.CheckInStatus.CheckIn);
		PropertyUtils.setProperty(reserve, "checkInType", GroupReserve.CheckInType.Alliance);
		List<AllianceSetlGridView> views = allSetlManager.querySetl(reserve);

		// 得到所有结算子表(入住联盟)
		List<Long> pklist = views.stream().map(a -> a.getAllianceSettlement().getPkAllianceSettlement())
				.collect(Collectors.toList());
		AllianceSetlDetail detail = new AllianceSetlDetail();
		PropertyUtils.setProperty(detail, "allianceSettlement.pkAllianceSettlementIn", pklist);
		List<AllianceSetlDetail> details = allSetlDetManager.query(detail);

		// 筛选入住联盟的结算单
		for (AllianceSetlGridView alliance : views) {
			if (alliance.getAllianceSettlement().getConfirmStatus().name().equals(status)) {
				// 选出已结算的结算单
				List<AllianceSetlDetail> allianceDetail = new ArrayList<AllianceSetlDetail>();
				for (AllianceSetlDetail adetail : details) {
					if (adetail.getAllianceSettlement().getPkAllianceSettlement()
							.equals(alliance.getAllianceSettlement().getPkAllianceSettlement())) {
						allianceDetail.add(adetail);
					}
				}
				int i = 0;
				for (AllianceSetlDetail setlDetail : allianceDetail) {
					if (setlDetail.getFinish()) {
						i++;
					}
				}

				if (i != 0 && i == allianceDetail.size()) {
					SettlementView view = new SettlementView();
					view.setPk(alliance.getAllianceSettlement().getPkAllianceSettlement());
					view.setVersion(alliance.getAllianceSettlement().getVersion());
					view.setName(alliance.getAllianceConfirm().getGroupReserve().getPlanItemGroup().getPlanItem()
							.getDestination().getName());
					view.setType("直属入住联盟");
					view.setCheckInDate(alliance.getAllianceConfirm().getGroupReserve().getCheckInDate());
					view.setCheckOutDate(alliance.getAllianceConfirm().getGroupReserve().getCheckOutDate());
					view.setBalance(alliance.getAllianceSettlement().getBalance());
					view.setConfirmStatus(alliance.getAllianceSettlement().getConfirmStatus().name());
					view.setConfirmDate(alliance.getAllianceSettlement().getConfirmDate());
					view.setPlanItem(alliance.getAllianceConfirm().getGroupReserve().getPlanItemGroup()
							.getServicePoint().getName());
					view.setPaymentMethods(new ArrayList<>(alliance.getAllianceSettlement().getPaymentMethods()));
					view.setGroupPk(alliance.getAllianceConfirm().getGroupReserve().getPkGroupReserve());
					if("all".equals(paymentMethod)){
						returnlist.add(view);
					}else{
						for(PaymentMethod p: alliance.getAllianceSettlement().getPaymentMethods()){
							if(paymentMethod.equals(p.toString())){
								returnlist.add(view);
								break;
							}
						}
					}
				}
			}
		}

		return returnlist;
	}

	@Override
	public CheckInImplement OrgConfirm(CheckInImplement cond) {
		CheckInImplement cii = ciimplementDao.get(cond.getPkCIImplement());
		cii.setConfirmStatus(CheckInImplement.ConfirmStatus.Confirm);
		cii.setConfirmDate(new Date());
		cii.setContent(cond.getContent());
		cii.setIsInvoice(cond.getIsInvoice());
		cii.setInvoiceDate(cond.getInvoiceDate());
		cii.setPayee(cond.getPayee());
		cii.setPayer(cond.getPayer());
		cii.setConfirmUser((CommonUser) AppContext.curUser());
		return save(cii);
	}

	@Override
	public AllianceSettlement AllianceConfirm(AllianceSettlement cond) {
		AllianceSettlement alliance = allSetlManager.get(cond.getPkAllianceSettlement());
		alliance.setConfirmStatus(AllianceSettlement.ConfirmStatus.Confirm);
		alliance.setConfirmDate(new Date());
		alliance.setContent(cond.getContent());
		alliance.setIsInvoice(cond.getIsInvoice());
		alliance.setInvoiceDate(cond.getInvoiceDate());
		alliance.setPayee(cond.getPayee());
		alliance.setPayer(cond.getPayer());
		alliance.setConfirmUser((CommonUser) AppContext.curUser());
		return allSetlManager.save(alliance);
	}

	@Override
	public List<ChangeRoomSettlementView> queryChangeRoom(Long pkGroupReserve) {
		return ciimplementDao.queryChangeRoom(pkGroupReserve);
	}

	@Override
	public ImplementView saveCheckIn(ImplementView cond) {
		ImplementView ilv = new ImplementView();
		Long pkCIImplement = cond.getCheckInImplement().getPkCIImplement();
		CheckInImplement checkInImplement = get(pkCIImplement);
		//Double checkInPrice = cond.getCheckInPrice();// 入住价
		CheckInType checkInType = cond.getCheckInType();// 入住类型
		List<RoomPersonalInfo> temp = cond.getTemp();// 个人信息

		Long pkGroupReserve = ciimplementDao.queryGroupReservePk(pkCIImplement);
		GroupReserve groupReserve = groupReserveM.get(pkGroupReserve);

		Long planItemGPk = planItemGroupM.queryPlanItemGPk(pkGroupReserve);
		PlanItemGroup planItemGroup = planItemGroupM.get(planItemGPk);

		planItemGroup.setCheckInStatus(CheckInStatus.CheckIn);
		planItemGroupM.save(planItemGroup);
		checkInImplement = save(checkInImplement);
		businessMessageManager.saveBusinessMessage(new BusinessMessage(TargetType.Role,TaskType.WaterElectricCheckOut,checkInImplement.getPkCIImplement()));

		// 回写房间状态为入住
		Set<Room> rmSet = new HashSet<>();
		Set<Long> set = new HashSet<Long>();
		for (int i = 0; i < temp.size(); i++) {
			Long pkRoomPersonalInfo = temp.get(i).getPkRoomPersonalInfo();
			Long pkRoomRegister = roomRegisterM.queryPk(pkRoomPersonalInfo);
			RoomRegister roomRegister = roomRegisterM.get(pkRoomRegister);
			roomRegister.setCheckInPrice(temp.get(i).getRoomRegister().getCheckInPrice());
			roomRegister.setCheckInType(checkInType);

			Room room = roomRegister.getRoom();
			room.setStatus(Status.CheckIn);
			rmSet.add(room);
			set.add(pkRoomRegister);
			roomRegisterM.save(roomRegister);
		}
		RoomRegister room = new RoomRegister();
		PropertyUtils.setProperty(room, "pkRoomRegisterIn", set);
		List<RoomRegister> roomList = roomRegisterM.query(room);
		// 根据房间去推送CheckIn
		for (RoomRegister r : roomList) {
			CheckIn checkIn = new CheckIn();
			checkIn.setRoomRegister(r);
			checkIn.setCheckInImplement(checkInImplement);
			checkIn.setCheckInDate(groupReserve.getCheckInDate());
			checkIn.setCheckOutDate(groupReserve.getCheckOutDate());
			checkIn.setRegisterDate(new Date());
			checkIn.setOperator(cond.getOperator());
			checkIn.setServicePoint(checkInImplement.getServicePoint());//
			checkIn.setStatus(com.eling.elcms.travel.model.CheckIn.Status.CheckIn);
			checkIn.setCheckOutStatus(CheckOutStatus.NoCheckOut);
			checkInManager.save(checkIn);
		}

		if (!rmSet.isEmpty()) {
			roomManager.save(new ArrayList<>(rmSet));
		}
		return ilv;
	}

	@Override
	public List<CheckInImplement> querycheckin(CheckInImplement checkInImplement) {
		List<CheckInImplement> list = query(checkInImplement);
		return Manage(list);
	}

	@Override
	public List<CheckInImplement> searchCheckIn(SearchCondition sc) {
		List<CheckInImplement> list = search(sc);
		return Manage(list);
	}

	private List<CheckInImplement> Manage(List<CheckInImplement> list) {
		Long pkRoomType = null;
		Double vipPrice = null;
		for (int i = 0; i < list.size(); i++) {
			CheckInImplement c = list.get(i);
			Set<RoomRegister> roomRegisters = list.get(i).getGroupReserve().getRoomRegisters();
			for (RoomRegister r : roomRegisters) {
				pkRoomType = r.getRoom().getRoomType().getPkRoomType();
				break;
			}
			RoomTypePrice cond = new RoomTypePrice();
			if (pkRoomType != null) {
				PropertyUtils.setProperty(cond, "roomType.pkRoomType", pkRoomType);
			}
			List<RoomTypePrice> roomTypePriceList = roomTypePriceM.query(cond);
			for (RoomTypePrice rt : roomTypePriceList) {
				vipPrice = rt.getVipPrice();
				// 这个设置的是vip 会员房价 只是在前台页面显示用
				c.setVipPrice(vipPrice);
				break;
			}
			list.remove(i);
			list.add(i, c);
		}
		return list;
	}

	@Override
	public List<WaterElectricGroupView> waterElectricGroup(String checkInStatus, Long pkServicePoint, Date startDate,
			Date endDate) {
		List<CheckInImplement> checkList = new ArrayList<>();
		CheckInImplement cii = new CheckInImplement();
		// 查询机构、联盟团的入住准备落实单
		PropertyUtils.setProperty(cii, "dataSource", DataSource.GroupReserve);
		PropertyUtils.setProperty(cii, "roomStatus", CheckStatus.Pended);
		PropertyUtils.setProperty(cii, "servicePoint.pkServicePoint", pkServicePoint);
		PropertyUtils.setProperty(cii, "groupReserve.orderString", "checkInDate:desc");
		PropertyUtils.setProperty(cii, "groupReserve.checkInDate", startDate);
		PropertyUtils.setProperty(cii, "groupReserve.checkInDateEnd", endDate);
		PropertyUtils.setProperty(cii, "orderString", "groupReserve.checkInDate");
		List<CheckInImplement> ciiOneList = ciimplementDao.query(cii);
		if (!ciiOneList.isEmpty()) {
			for (CheckInImplement ciiOne : ciiOneList) {
				if (ciiOne.getGroupReserve().getPlanItemGroup().getIsAbolished() == null
						|| !ciiOne.getGroupReserve().getPlanItemGroup().getIsAbolished()) {
					checkList.add(ciiOne);
				}
			}
		}
		
		//散客
		CheckInImplement nonCii = new CheckInImplement();
		PropertyUtils.setProperty(nonCii, "dataSource", DataSource.NonMember);
		PropertyUtils.setProperty(nonCii, "roomStatus", CheckStatus.Pended);
		PropertyUtils.setProperty(nonCii, "nonMemGroupReserve.nonMemberGroup.statusIn", com.eling.elcms.travel.model.NonMemberGroup.Status.CheckIn);
		PropertyUtils.setProperty(nonCii, "servicePoint.pkServicePoint", pkServicePoint);
		PropertyUtils.setProperty(nonCii, "nonMemGroupReserve.nonMemberGroup.orderString", "checkInDate:desc");
		PropertyUtils.setProperty(nonCii, "nonMemGroupReserve.nonMemberGroup.checkInDate", startDate);
		PropertyUtils.setProperty(nonCii, "nonMemGroupReserve.nonMemberGroup.checkInDateEnd", endDate);
		PropertyUtils.setProperty(nonCii, "nonMemGroupReserve.nonMemberGroup.isWaterElectric", false);
		PropertyUtils.setProperty(nonCii, "orderString", "nonMemGroupReserve.nonMemberGroup.checkInDate");
		List<CheckInImplement> ciiNonList = ciimplementDao.query(nonCii);
		
		List<WaterElectricGroupView> returnList = new ArrayList<>();
		
		//团
		for (int i = 0; i < checkList.size(); i++) {
			CheckInImplement checkInImplement = checkList.get(i);
			WaterElectricGroupView waterElectricGroupView = new WaterElectricGroupView();
			waterElectricGroupView.setCheckInImplement(checkInImplement);
			List<RoomPersonalInfo> rpiList = new ArrayList<>(checkInImplement.getRoomPersonalInfos());
			Set<RoomRegister> roomRegisters = new HashSet<>(rpiList.stream().map(a->a.getRoomRegister()).collect(Collectors.toList()));
			int countO = 0;
			int countT = 0;
			for (RoomRegister roomRegister : roomRegisters) {
				if(RoomStatus.CheckIn.equals(roomRegister.getRoomStatus())){
					countO ++;
				}
				if(RoomStatus.finish.equals(roomRegister.getRoomStatus())){
					countT ++;
				}
			}
			if(countO == roomRegisters.size()){
				waterElectricGroupView.setCheckInStatus(WaterElectricGroupView.CheckInStatus.CheckIn);
			}else if(countT == roomRegisters.size()){
				waterElectricGroupView.setCheckInStatus(WaterElectricGroupView.CheckInStatus.Accomplish);
			}else if(countO+countT==roomRegisters.size()){
				waterElectricGroupView.setCheckInStatus(WaterElectricGroupView.CheckInStatus.CheckIn);
			}else {
				waterElectricGroupView.setCheckInStatus(WaterElectricGroupView.CheckInStatus.NoCheckIn);
			}
			returnList.add(waterElectricGroupView);
		}
		//散客
		for (int i = 0; i < ciiNonList.size(); i++) {
			WaterElectricGroupView waterElectricGroupView = new WaterElectricGroupView();
			CheckInImplement checkInImplement = ciiNonList.get(i);
			waterElectricGroupView.setCheckInImplement(checkInImplement);
			Set<RoomPersonalInfo> roomPersonalInfos = checkInImplement.getRoomPersonalInfos();
			int countO = 0;
			int countT = 0;
			Set<RoomRegister> roomRegisters = new HashSet<>();
			Set<Long> roomPks = new HashSet<>();
			for (RoomPersonalInfo roomPersonalInfo : roomPersonalInfos) {
				//散客一个roomPersonalinfo对应一个roomregister，所以有两个人住同一房间情况需要排除掉
				if(roomPersonalInfo.getRoomRegister().getRoom()==null||roomPersonalInfo.getRoomRegister().getRoom().getPkRoom()==null||
						(!roomPks.isEmpty() && roomPks.contains(roomPersonalInfo.getRoomRegister().getRoom().getPkRoom()))){
					continue;
				}
				if(roomPersonalInfo.getRoomRegister().getRoom()!=null){
					roomPks.add(roomPersonalInfo.getRoomRegister().getRoom().getPkRoom());
				}
				RoomRegister roomRegister = roomPersonalInfo.getRoomRegister();
				roomRegisters.add(roomRegister);
				if(RoomStatus.CheckIn.equals(roomRegister.getRoomStatus())){
					countO ++;
				}
				if(RoomStatus.finish.equals(roomRegister.getRoomStatus())){
					countT ++;
				}
			}
			if(countO == roomPks.size()){
				waterElectricGroupView.setCheckInStatus(WaterElectricGroupView.CheckInStatus.CheckIn);
			}else if(countT == roomPks.size()){
				waterElectricGroupView.setCheckInStatus(WaterElectricGroupView.CheckInStatus.Accomplish);
			}else if(countO+countT==roomPks.size()){
				waterElectricGroupView.setCheckInStatus(WaterElectricGroupView.CheckInStatus.CheckIn);
			}else {
				waterElectricGroupView.setCheckInStatus(WaterElectricGroupView.CheckInStatus.NoCheckIn);
			}
			waterElectricGroupView.setRoomCount(roomRegisters==null?0:roomRegisters.size());
			returnList.add(waterElectricGroupView);
		}
		
		List<WaterElectricGroupView> list = new ArrayList<>();
		if(WaterElectricGroupView.CheckInStatus.CheckIn.toString().equals(checkInStatus)){
			for (WaterElectricGroupView waterElectricGroupView : returnList) {
				if(WaterElectricGroupView.CheckInStatus.CheckIn.equals(waterElectricGroupView.getCheckInStatus())){
					list.add(waterElectricGroupView);
				}
			}
			return list;
		} if(WaterElectricGroupView.CheckInStatus.NoCheckIn.toString().equals(checkInStatus)){
			for (WaterElectricGroupView waterElectricGroupView : returnList) {
				if(WaterElectricGroupView.CheckInStatus.NoCheckIn.equals(waterElectricGroupView.getCheckInStatus())){
					list.add(waterElectricGroupView);
				}
			}
			return list;
		} if(WaterElectricGroupView.CheckInStatus.Accomplish.toString().equals(checkInStatus)){
			for (WaterElectricGroupView waterElectricGroupView : returnList) {
				if(WaterElectricGroupView.CheckInStatus.Accomplish.equals(waterElectricGroupView.getCheckInStatus())){
					list.add(waterElectricGroupView);
				}
			}
			return list;
		}
		return returnList;
	}
	
	@Override
	public List<CheckInImplement> search(SearchCondition sc) {
		String s = sc.getS();
		List<CheckInImplement> checkList = getAll();
		List<CheckInImplement> returnList = new ArrayList<>();
		for (CheckInImplement check : checkList) {
			if(check.getServicePoint() !=null && check.getServicePoint().getName().contains(s)){
				returnList.add(check);
				continue;
			}
			if(check.getDataSource().equals(DataSource.GroupReserve) &&
					check.getGroupReserve().getPlanItemGroup().getPlanItem().getDestination().getName().contains(s)){
				returnList.add(check);
				continue;
			}
			if(check.getDataSource().equals(DataSource.NonMember) &&(
					check.getNonMemGroupReserve().getNonMemberGroup().getServicePoint().getName().contains(s) || 
					check.getNonMemGroupReserve().getNonMemberGroup().getContactName().contains(s))){
				returnList.add(check);
				continue;
			}
		}
		return returnList;
	}

	@Override
	public List<CheckInImplement> queryNoStatementTeam(CheckInImplement cond) {
		
		List<CheckInImplement> returnList = new ArrayList<>();
		{
			//已预约或 已登记 且没有结算的老人团
			CheckInImplement cii = new CheckInImplement();
			PropertyUtils.setProperty(cii, "groupReserve.planItemGroup.checkInStatusIn", "Reserve,CheckIn");
			PropertyUtils.setProperty(cii, "statementStatus", StatementStatus.NoStatement);
			List<CheckInImplement> queryGroupReserve = query(cii);
			returnList.addAll(queryGroupReserve);
		}
		
		{
			//已预约或 已登记 且没有结算的散客  
			CheckInImplement ciim = new CheckInImplement();
			PropertyUtils.setProperty(ciim, "nonMemGroupReserve.nonMemberGroup.statusIn", "Effective,CheckIn");
			PropertyUtils.setProperty(ciim, "statementStatus", StatementStatus.NoStatement);
			List<CheckInImplement> queryNonMemGroupReserve = query(ciim);
			returnList.addAll(queryNonMemGroupReserve);
		}
		
		//去重操作
		Set<CheckInImplement> setlist = new HashSet<CheckInImplement>(returnList);
		returnList = new ArrayList<CheckInImplement>(setlist);
		
		
		Collections.sort(returnList,new Comparator<CheckInImplement>() {
			public int compare(CheckInImplement o1, CheckInImplement o2) {
				Date date1 = null;
				Date date2 = null;
				//散客
				if(o1.getDataSource()==DataSource.NonMember || o1.getDataSource()==DataSource.VisitDoorFIT ){
					date1 = o1.getNonMemGroupReserve().getNonMemberGroup().getCheckInDate();
				}else{//老人团
					date1 = o1.getGroupReserve().getCheckInDate();
				}
				//散客
				if(o2.getDataSource()==DataSource.NonMember || o2.getDataSource()==DataSource.VisitDoorFIT ){
					date2 = o2.getNonMemGroupReserve().getNonMemberGroup().getCheckInDate();
				}else{//老人团
					date2 = o2.getGroupReserve().getCheckInDate();
				}
				return date2.compareTo(date1);
			};
		});
		
		return returnList;
		
		
	}

	@Override
	public CheckInImplement changeOnCredit(CheckInImplement cond) {
		CheckInImplement checkInImplement = new CheckInImplement();
		checkInImplement.setPkCIImplement(cond.getPkCIImplement());
		checkInImplement = query(checkInImplement).get(0);
		checkInImplement.setIsSales(cond.getIsSales());
		Double balance = checkInImplement.getBalance() + checkInImplement.getOnCreditMoney();
		checkInImplement.setBalance(balance);
		return save(checkInImplement);
	}

	@Override
	public List<CheckInImplement> queryByPaymentMethod(CheckInImplement checkInImplement, String paymentMethod) {
		
		List<CheckInImplement> returnList = new ArrayList<>();
		List<CheckInImplement> checkInImplements = query(checkInImplement);
		for(CheckInImplement c : checkInImplements){
			for(PaymentMethod p: c.getPaymentMethods()){
				if(paymentMethod.equals(p.toString())){
					returnList.add(c);
					break;
				}
			}
		}
		return returnList;
	}
	
}
